package com.ecoolex.discount.sales.api.graphql;

import com.ecoolex.discount.sales.entity.*;
import com.ecoolex.discount.sales.enums.DiscountOrderCompleteStatus;
import com.ecoolex.discount.sales.enums.DiscountOrderProcessStatus;
import com.ecoolex.discount.sales.enums.DiscountOrderStatus;
import com.ecoolex.discount.sales.pojo.CreateOrderChannelDTO;
import com.ecoolex.discount.sales.pojo.QueryUserDiscountOrderDTO;
import com.ecoolex.discount.sales.ws.DiscountOrderService;
import com.ecoolex.discount.sales.ws.DiscountProductService;
import com.ecoolex.discount.sales.ws.PaymentOrderService;
import com.ecoolex.framework.common.annotation.Description;
import com.ecoolex.framework.common.enums.ResultCode;
import com.ecoolex.framework.common.pojo.Page;
import com.ecoolex.framework.common.pojo.Pagination;
import com.ecoolex.framework.common.pojo.Sorting;
import com.ecoolex.framework.common.util.Assert;
import com.ecoolex.framework.common.util.Check;
import com.ecoolex.framework.common.util.io.HttpUtil;
import com.ecoolex.framework.modularize.api.auth.user.ConsumerMemberAuthority;
import com.ecoolex.framework.web.api.graphql2.annotation.*;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.lang.NonNull;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

@GraphQL2Module(type = GraphQL2Module.Type.User, description = "折扣订单")
public class DiscountOrderGraphql {

    @Reference
    private DiscountOrderService discountOrderService;
    @Reference
    private PaymentOrderService paymentOrderService;
    @Reference
    private DiscountProductService discountProductService;

    @TypeField(type = DiscountOrder.class, field = "canPay", description = "是否能支付")
    public boolean canPay(@Source DiscountOrder source) {
        return DiscountOrderStatus.canPay(source);
    }
    
    @TypeField(type = DiscountOrder.class, field = "canRefund", description = "是否能退款")
    public boolean canRefund(@Source DiscountOrder source) {
        return DiscountOrderStatus.canRefund(source);
    }
    
    @TypeField(type = DiscountOrder.class, field = "canCancelRefund", description = "是否能取消退款")
    public boolean canCancelRefund(@Source DiscountOrder source) {
        return DiscountOrderStatus.canCancelRefund(source);
    }

    @TypeField(type = DiscountOrder.class, field = "canCancel", description = "是否能取消")
    public boolean canCancel(@Source DiscountOrder source) {
        return DiscountOrderStatus.canCancel(source);
    }

    @TypeField(type = DiscountOrder.class, field = "canDel", description = "是否能删除")
    public boolean canDel(@Source DiscountOrder source) {
        return DiscountOrderStatus.canDel(source);
    }

    @TypeField(type = DiscountOrder.class, field = "canConfirmComplete", description = "是否能确认完成")
    public boolean canConfirmComplete(@Source DiscountOrder source) {
        return DiscountOrderStatus.canConfirmComplete(source) &&
        	DiscountOrderCompleteStatus.canConfirmComplete(source);
    }
    
    @TypeField(type = DiscountOrder.class, field = "canPartConfirmComplete", description = "是否能部分确认完成")
    public boolean canPartConfirmComplete(@Source DiscountOrder source) {
        return DiscountOrderStatus.canPartConfirmComplete(source) &&
        	DiscountOrderProcessStatus.canPartConfirmComplete(source) && 
        	DiscountOrderCompleteStatus.canPartConfirmComplete(source);
    }
    
    @TypeField(type = DiscountOrder.class, field = "discountOrderRefund", description = "最新一条退款单")
    public DiscountOrderRefund discountOrderRefund(@Source DiscountOrder source) {
    	return discountOrderService.getByOrderId(source.getOrderId());
    }

    @TypeField(type = DiscountOrder.class, field = "detailList", description = "订单详细列表")
    public List<DiscountOrderDetail> detailList(@Source DiscountOrder source) {
        // 没有处理完成的
        if (DiscountOrderProcessStatus.PROCESS_SUCCEED.notEqual(source.getProcessStatus())) {
            return null;
        }

        return discountOrderService.queryOrderDetailByOrderId(source.getOrderId());
    }
    
    @TypeField(type = DiscountOrderDetail.class, field = "youWorldGiftCardOrder", description = "由我礼品卡订单")
    public YouWorldGiftCardOrder youWorldGiftCardOrder(@Source DiscountOrderDetail source) {
    	return discountOrderService.getByOrderId(source.getTransNo());
    }

    @TypeField(type = DiscountOrder.class, field = "brand", description = "折扣品牌")
    public DiscountBrandWithBLOBs brand(@Source DiscountOrder source) {
        return discountProductService.getDiscountBrand(source.getBrandId());
    }

    @TypeField(type = DiscountOrder.class, field = "product", description = "折扣产品")
    public DiscountProductWithBLOBs product(@Source DiscountOrder source) {
        return discountProductService.getProductById(source.getProductId());
    }
    
    @TypeField(type = DiscountOrderDetail.class, field = "product", description = "折扣产品")
    public DiscountProductWithBLOBs product(@Source DiscountOrderDetail source) {
        return discountProductService.getProductById(source.getProductId());
    }

    @TypeField(type = CardVoucherPackage.class, field = "product", description = "折扣产品")
    public DiscountProductWithBLOBs product(@Source CardVoucherPackage source) {
        return discountProductService.getProductById(source.getProductId());
    }

    @TypeField(type = CardVoucherPackage.class, field = "order", description = "订单")
    public DiscountOrder order(@Source CardVoucherPackage source) {
        return discountOrderService.getOrderById(source.getOrderId());
    }

    @QueryField(field = "discountOrder", description = "折扣订单详情")
    public DiscountOrder getOrderById(@NonNull Integer orderId, ConsumerMemberAuthority user) {
        user.assertLogin();
        return discountOrderService.getOrderById(user.userId(), orderId);
    }

    @QueryField(field = "discountOrderList", description = "查询折扣订单列表")
    public Pagination<DiscountOrder> queryOrderByUserId(@NonNull QueryUserDiscountOrderDTO query, @NonNull Sorting[] sorts, @NonNull Page page, ConsumerMemberAuthority user) {
        user.assertLogin();
        return discountOrderService.queryOrderByUserId(user.userId(), query, sorts, page);
    }

    @MutationField(field = "createQuotaGiftCardDiscountOrder", description = "创建定额礼品卡折扣订单")
    public DiscountOrder createQuotaGiftCardOrder(@NonNull Integer productId,CreateOrderChannelDTO channel, ConsumerMemberAuthority user) {
        user.assertLogin();
        return discountOrderService.createQuotaGiftCardOrder(user.userId(), productId,channel, user.userName());
    }

    @MutationField(field = "createGiftCardDiscountOrder", description = "创建礼品卡折扣订单")
    public DiscountOrder createGiftCardOrder(@NonNull Integer productId, @NonNull BigDecimal faceValue,CreateOrderChannelDTO channel, ConsumerMemberAuthority user) {
        user.assertLogin();
        return discountOrderService.createGiftCardOrder(user.userId(), productId, faceValue,channel, user.userName());
    }

    @MutationField(field = "createVouchersDiscountOrder", description = "创建卡/券折扣订单")
    public DiscountOrder createVouchersOrder(@NonNull Integer productId, @NonNull Integer buyNumber,CreateOrderChannelDTO channel, ConsumerMemberAuthority user) {
        user.assertLogin();
        return discountOrderService.createVouchersOrder(user.userId(), productId, buyNumber,channel, user.userName());
    }

    @MutationField(field = "cancelDiscountOrder", description = "取消折扣订单")
    public boolean cancelOrder(@NonNull Integer orderId, ConsumerMemberAuthority user) {
        user.assertLogin();
        return discountOrderService.cancelOrder(user.userId(), orderId, user.userName());
    }

    @MutationField(field = "deleteDiscountOrder", description = "删除折扣订单")
    public boolean deleteOrder(@NonNull Integer orderId, ConsumerMemberAuthority user) {
        user.assertLogin();
        return discountOrderService.deleteOrder(user.userId(), orderId, user.userName());
    }

    @MutationField(field = "confirmCompleteDiscountOrder", description = "确认完成折扣订单")
    public boolean confirmCompleteOrder(@NonNull Integer orderId, ConsumerMemberAuthority user) {
        user.assertLogin();
        return discountOrderService.confirmCompleteOrder(user.userId(), orderId, user.userName());
    }
    
    @MutationField(field = "confirmPartCompleteDiscountOrder", description = "确认部分使用折扣订单")
    public boolean confirmPartCompleteOrder(@NonNull Integer orderId, ConsumerMemberAuthority user) {
        user.assertLogin();
        return discountOrderService.confirmPartCompleteOrder(user.userId(), orderId, user.userName());
    }

    @MutationField(field = "initiateDiscountOrderWXPayment", description = "发起微信支付折扣订单")
    public Map initiateDiscountOrderWXPayment(@NonNull String appId, @NonNull Integer orderId, HttpServletRequest request, ConsumerMemberAuthority user) {
        user.assertLogin();
        DiscountOrder order = discountOrderService.getOrderById(user.userId(), orderId);
        Assert.isTrue(Check.notNull(order), ResultCode.VERIFY.build(1), "订单不存在");
        Assert.isTrue(DiscountOrderStatus.canPay(order), ResultCode.VERIFY.build(2), "订单无法发起支付");
        Map result = paymentOrderService.weiXinPayApply(order, appId, HttpUtil.getIpAddr(request), this.getClass().getSimpleName());
        Assert.isTrue(Check.notNull(result), ResultCode.VERIFY.build(3), "订单发起支付失败");
        return result;
    }
    
    @MutationField(field = "initiateDiscountOrderNihaoPayPayment", description = "发起NihaoPay支付折扣订单")
    public String initiateDiscountOrderNihaoPayPayment(@Description({"支付方式：1-unionpay;2-wechatpay;3-alipay"}) @NonNull Integer nihaopayType, 
    	@NonNull Integer orderId, HttpServletRequest req,HttpServletResponse resp, ConsumerMemberAuthority user) {
        user.assertLogin();
        DiscountOrder order = discountOrderService.getOrderById(user.userId(), orderId);
        Assert.isTrue(Check.notNull(order), ResultCode.VERIFY.build(1), "订单不存在");
        Assert.isTrue(DiscountOrderStatus.canPay(order), ResultCode.VERIFY.build(2), "订单无法发起支付");
        String result = paymentOrderService.nihaoPayApply(nihaopayType,order,req,resp, this.getClass().getSimpleName());
        Assert.isTrue(Check.notNull(result), ResultCode.VERIFY.build(3), "订单发起支付失败");
        return result;
    }
    
    @MutationField(field = "applyDiscountOrderRefund", description = "发起退款")
    public Boolean applyRefund(@NonNull Integer orderId, @Description({"是否使用过"})@NonNull Boolean cardUsed,
    	@Description({"退款类型"})@NonNull String reasonType,@Description({"退款原因"}) String reasonComments,
    	@Description({"是否使用绑定的手机号"})@NonNull Boolean useBindPhone,@Description({"联系电话"}) String contactPhone,
    	ConsumerMemberAuthority user) {
    	user.assertLogin();
    	DiscountOrder order = discountOrderService.getOrderById(user.userId(), orderId);
        Assert.isTrue(Check.notNull(order), ResultCode.VERIFY.build(1), "订单不存在");
        Assert.isTrue(DiscountOrderStatus.canRefund(order), ResultCode.VERIFY.build(2), "订单无法发起退款");
        return discountOrderService.refund(order, cardUsed, reasonType, reasonComments, useBindPhone, contactPhone, user.userName());
    }
    
    @MutationField(field = "cancelDiscountOrderRefund", description = "取消退款")
    public Boolean cancelRefund(@NonNull Integer orderId, ConsumerMemberAuthority user) {
    	user.assertLogin();
    	DiscountOrder order = discountOrderService.getOrderById(user.userId(), orderId);
        Assert.isTrue(Check.notNull(order), ResultCode.VERIFY.build(1), "订单不存在");
        Assert.isTrue(DiscountOrderStatus.canCancelRefund(order), ResultCode.VERIFY.build(2), "订单无法取消退款");
        return discountOrderService.cancelRefund(order, user.userName());
    }

    @QueryField(field = "cardVoucherPackageList", description = "卡券包列表")
    public Pagination<CardVoucherPackage> queryCardVoucherPackageByUserId(Integer discountMode, @NonNull Page page, ConsumerMemberAuthority user) {
        user.assertLogin();
        return discountOrderService.queryCardVoucherPackage(user.userId(),page, discountMode);
    }
    
    @QueryField(field = "cardVoucherPackage", description = "卡券包详情")
    public CardVoucherPackage getCardVoucherPackageByUserId(Integer cardVoucherId, ConsumerMemberAuthority user) {
        user.assertLogin();
        return discountOrderService.getCardVoucherPackage(cardVoucherId,user.userId());
    }
}
